/**********************************************************************************************************************
 *
 * Project:    mGameEngine
 * File:       camera.h
 * Author:     karooolek
 * Created on: 2009-03-11
 *
 **********************************************************************************************************************/

#ifndef CAMERA_H_
#define CAMERA_H_

#include "../common.h"

namespace mGameEngine
{
namespace Graphics
{

/**
 * Interface for graphics scene cameras.
 */
class Camera
{
protected:
    /**
     * Camera aspect ratio.
     */
    float _ratio;

    /**
     * Camera automatic aspect ratio computation.
     */
    bool _autoRatio;

    /**
     * Camera near clipping plane distance.
     */
    float _nearClip;

    /**
     * Camera far clipping plane distance.
     */
    float _farClip;

public:
    /**
     * Create new camera.
     */
    Camera();

    /**
     * Create new camera with specified aspect radio and clipping planes.
     * @param ratio aspect ratio.
     * @param autoRatio automatic aspect ratio calculation.
     * @param nearClip near clipping plane distance.
     * @param farClip far clipping plane distance.
     */
    Camera(float ratio, bool autoRatio, float nearClip, float farClip);

    /**
     * Destroy camera.
     */
    virtual ~Camera();

    /**
     * Get camera aspect ratio.
     * @return camera aspect ratio.
     */
    float getAspectRatio() const
    {
        return _ratio;
    }

    /**
     * Set camera aspect ratio.
     * @param ratio aspect ratio.
     */
    void setAspectRatio(float ratio)
    {
        _ratio = abs(ratio);
    }

    /**
     * Get camera automatic aspect ratio computation.
     * @return camera automatic aspect ratio computation.
     */
    bool getAutoAspectRatio() const
    {
        return _autoRatio;
    }

    /**
     * Set camera automatic aspect ratio computation.
     * @param autoRatio automatic aspect ratio computation.
     */
    void setAutoAspectRatio(bool autoRatio)
    {
        _autoRatio = autoRatio;
    }

    /**
     * Get camera near clipping plane distance.
     * @return camera near clipping plane distance.
     */
    float getNearClippingPlane() const
    {
        return _nearClip;
    }

    /**
     * Set camera near clipping plane distance.
     * @param nearClip near clipping plane distance.
     */
    void setNearClippingPlane(float nearClip)
    {
        _nearClip = nearClip;
    }

    /**
     * Get camera far clipping plane distance.
     * @return camera far clipping plane distance.
     */
    float getFarClippingPlane() const
    {
        return _farClip;
    }

    /**
     * Set camera far clipping plane distance.
     * @param farClip far clipping plane distance.
     */
    void setFarClippingPlane(float farClip)
    {
        _farClip = farClip;
    }

    /**
     * Project world position to window coordinates.
     * @param position world position.
     * @return world position projected to window coordinates.
     */
    virtual const Vector3 &project(const Vector3 &position) const;

    /**
     * Unproject window coordinates to world coordinates.
     * @param wndCoords window coordinates.
     * @return window coordinates unprojected to world position.
     */
    virtual const Vector3 &unproject(const Vector3 &wndCoords) const;

    /**
     * Test if sphere is visible in camera.
     * @param sphere sphere in camera coordinates.
     * @return true if sphere is all or partially visible, false otherwise
     */
    virtual bool isInCamera(const Sphere &sphere) const = 0;

    /**
     * Calculate relative projected sphere size.
     * @param sphere sphere in camera coordinates.
     * @return projected sphere size relative to fov.
     */
    virtual float getProjectedSize(const Sphere &sphere) const = 0;

    /**
     * Use camera as active.
     */
    virtual void use() const = 0;
};

}
}

#endif // CAMERA_H_
